﻿using System;
using GenericTests.Entities;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace GenericTests
{
    /// <summary>
    /// Summary description for EntityBehaviour
    /// </summary>
    [TestClass]
    public class EntityBehaviour
    {
        public EntityBehaviour()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        #region Additional test attributes

        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //

        #endregion

        /// <summary>
        /// Teste para a Verificação do Processo de Instancia das Entidades
        /// </summary>
        [TestMethod()]
        public void InstanceTest()
        {
            // Instancia Entidade
            try
            {
                for (int x = 0; x > 1000; x++)
                {
                    User user = new User();
                }
            }
            catch (Exception e)
            {
                Assert.Fail("Não foi possível instanciar a entidade User.\n" + e.Message);
            }
        }

        /// <summary>
        /// Teste para a Verificação dos Acessores Dinâmicos de Leitura de uma Entidade
        /// </summary>
        [TestMethod()]
        public void DynamicPropertyReadAccessTest()
        {
            // Instancia Objeto
            User user = new User();
            int newID;
            string newLogin;
            string newPassword;
            string newName;

            // Looping para Teste de Leitura
            for (int x = 0; x < 1000; x++)
            {
                // Cria Valores
                newID = DateTime.Now.Second;
                newLogin = DateTime.Today.Millisecond.ToString();
                newPassword = Environment.TickCount.ToString();
                newName = DateTime.Now.Ticks.ToString();

                // Atribui Valores
                user.IDUser = newID;
                user.Login = newLogin;
                user.Password = newPassword;
                user.FullName = newName;

                // Recupera por Reflexão e Testa
                Assert.AreEqual(newID, user["IDUser"]);
                Assert.AreEqual(newLogin, user["Login"]);
                Assert.AreEqual(newPassword, user["Password"]);
                Assert.AreEqual(newName, user["FullName"]);
            }
        }

        /// <summary>
        /// Teste para a Verificação dos Acessores Dinâmicos de Gravação de uma Entidade
        /// </summary>
        [TestMethod()]
        public void DynamicPropertyWriteAccessTest()
        {
            // Instancia Objeto
            User user = new User();
            int newID;
            string newLogin;
            string newPassword;
            string newName;

            // Looping para Teste de Leitura
            for (int x = 0; x < 1000; x++)
            {
                // Cria Valores
                newID = DateTime.Now.Second;
                newLogin = DateTime.Today.Millisecond.ToString();
                newPassword = Environment.TickCount.ToString();
                newName = DateTime.Now.Ticks.ToString();

                // Atribui Valores por Reflexão
                user["IDUser"] = newID;
                user["Login"] = newLogin;
                user["Password"] = newPassword;
                user["FullName"] = newName;

                // Testa os Valores
                Assert.AreEqual(newID, user.IDUser);
                Assert.AreEqual(newLogin, user.Login);
                Assert.AreEqual(newPassword, user.Password);
                Assert.AreEqual(newName, user.FullName);
            }
        }

        /// <summary>
        /// Valida a Tag de IsDeleted
        /// </summary>
        [TestMethod()]
        public void IsDeletedTest()
        {
            // Cria Objeto
            User user = new User();

            // Verifica a Tag
            Assert.AreEqual(user.IsDeleted, false);

            // Marca para Exclusão
            user.MarkDeleted();

            // Verifica a Tag
            Assert.AreEqual(user.IsDeleted, true);
        }

        /// <summary>
        /// Valida a Tag de IsDirty
        /// </summary>
        [TestMethod()]
        public void IsDirtyTest()
        {
            // Cria Objeto
            User user = new User();

            // Verifica a Tag
            Assert.AreEqual(user.IsDirty, false);

            // Modifica uma Propriedade
            user.IDUser = 1;

            // Verifica a Tag
            Assert.AreEqual(user.IsNew, true);
        }

        /// <summary>
        /// Valida a Tag de IsNew
        /// </summary>
        [TestMethod()]
        public void IsNewTest()
        {
            // Cria Objeto
            User user = new User();

            // Verifica a Tag
            Assert.AreEqual(user.IsNew, true);

            // Modifica uma Propriedade
            user.IDUser = 1;

            // Verifica a Tag
            Assert.AreEqual(user.IsNew, true);
        }

        /// <summary>
        /// Valida o Mecanismo de Edição para Instância de Classe
        /// </summary>
        [TestMethod()]
        public void IEditableTest_Instance()
        {
            // Cria Objeto
            User user = new User();

            // Verifica o Mecanismo de Edição
            Assert.IsFalse(user.Editing, "A Entidade não pode estar em edição assim que for inicializada");
        }

        /// <summary>
        /// Valida o Mecanismo de Edição para Mudança de Propriedade
        /// </summary>
        [TestMethod()]
        public void IEditableTest_PropertyChange()
        {
            // Cria Objeto
            User user = new User();

            // Muda Valores
            user.IDUser = 1;
            user.Login = "xpto";

            // Verifica o Mecanismo de Edição
            Assert.IsFalse(user.Editing, "A Entidade não pode estar em edição quando suas propriedades forem alteradas");
        }

        /// <summary>
        /// Valida o Mecanismo de Edição para o Ciclo Completo de Testes para o Fim da Edição
        /// </summary>
        [TestMethod()]
        public void IEditableTest_FullCycle_EndEdit()
        {
            // Cria Objeto
            User user = new User();
            int firstID = 1;
            int newID = 99;
            string firstLogin = "xooi";
            string newLogin = "qwert";

            // Muda Valores
            user.IDUser = firstID;
            user.Login = firstLogin;


            // Inicia Edição
            user.BeginEdit();

            // Verifica se os Valores são os Mesmos (Devem ser)
            Assert.AreEqual(user.IDUser, firstID, "A propriedade deve ter o mesmo valor após o comando BeginEdit()");
            Assert.AreEqual(user.Login, firstLogin, "A propriedade deve ter o mesmo valor após o comando BeginEdit()");


            // Muda as Propriedades para os Novos Valores
            user.IDUser = newID;
            user.Login = newLogin;

            // Finaliza Edição
            user.EndEdit();

            // Varifica as Propriedades para Ver se Mudaram
            Assert.AreEqual(user.IDUser, newID,
                            "Após a Finalização da Edição, os valores das propriedades devem ser os mesmos colocados na edição.");
            Assert.AreEqual(user.Login, newLogin,
                            "Após a Finalização da Edição, os valores das propriedades devem ser os mesmos colocados na edição.");
        }

        /// <summary>
        /// Valida o Mecanismo de Edição para o Ciclo Completo de Testes para o Cancelamento da Edição
        /// </summary>
        [TestMethod()]
        public void IEditableTest_FullCycle_CancelEdit()
        {
            // Cria Objeto
            User user = new User();
            int firstID = 1;
            int newID = 99;
            string firstLogin = "xooi";
            string newLogin = "qwert";

            // Muda Valores
            user.IDUser = firstID;
            user.Login = firstLogin;


            // Inicia Edição
            user.BeginEdit();

            // Verifica se os Valores são os Mesmos (Devem ser)
            Assert.AreEqual(user.IDUser, firstID, "A propriedade deve ter o mesmo valor após o comando BeginEdit()");
            Assert.AreEqual(user.Login, firstLogin, "A propriedade deve ter o mesmo valor após o comando BeginEdit()");


            // Muda as Propriedades para os Novos Valores
            user.IDUser = newID;
            user.Login = newLogin;

            // Finaliza Edição
            user.CancelEdit();

            // Varifica as Propriedades para Ver se Mudaram
            Assert.AreEqual(user.IDUser, firstID, "Após o Cancelamento da Edição, os valores das propriedades devem ser os valores originais (Antes da Edição).");
            Assert.AreEqual(user.Login, firstLogin, "Após o Cancelamento da Edição, os valores das propriedades devem ser os valores originais (Antes da Edição).");
        }

        /// <summary>
        /// Valida o Mecanismo de Edição para EndEdit()
        /// </summary>
        [TestMethod()]
        public void IEditableTest_EndEdit()
        {
            // Cria Objeto
            User user = new User();

            // Muda Valores
            user.IDUser = 1;
            user.Login = "xpto";

            // Inicia Edição
            user.BeginEdit();

            // Finaliza Edição
            user.EndEdit();

            // Verifica o Mecanismo de Edição
            Assert.IsFalse(user.Editing, "A Entidade não deve estar em edição quando for dado o comando EndEdit()");
        }

        /// <summary>
        /// Valida o Mecanismo de Edição para CancelEdit()
        /// </summary>
        [TestMethod()]
        public void IEditableTest_CancelEdit()
        {
            // Cria Objeto
            User user = new User();

            // Muda Valores
            user.IDUser = 1;
            user.Login = "xpto";

            // Inicia Edição
            user.BeginEdit();

            // Cancela Edição
            user.CancelEdit();

            // Verifica o Mecanismo de Edição
            Assert.IsFalse(user.Editing, "A Entidade não deve estar em edição quando for dado o comando CancelEdit()");
        }

        /// <summary>
        /// Valida o Mecanismo de Edição para BeginEdit()
        /// </summary>
        [TestMethod()]
        public void IEditableTest_BeginEdit()
        {
            // Cria Objeto
            User user = new User();

            // Muda Valores
            user.IDUser = 1;
            user.Login = "xpto";

            // Inicia Edição
            user.BeginEdit();

            // Verifica o Mecanismo de Edição
            Assert.IsTrue(user.Editing, "A Entidade deve estar em edição quando for dado o comando BeginEdit()");
        }







        /// <summary>
        /// Valida o Mecanismo de Edição para Coleção em EndEdit()
        /// </summary>
        [TestMethod()]
        public void ICollectionEditableTest_EndEdit()
        {
            // Cria Objeto
            User user = new User();
            UserCollection userCollection = new UserCollection();

            // Muda Valores
            user.IDUser = 1;
            user.Login = "xpto";

            // Inicia Edição
            userCollection.BeginEdit();

            // Adiciona Usuário
            userCollection.Add(user);

            // Finaliza Edição
            userCollection.EndEdit();

            // Verifica o Mecanismo de Edição
            Assert.IsFalse(userCollection.Count != 1, "Falha ao Realizar o EndEdit() na Coleção");
        }

        /// <summary>
        /// Valida o Mecanismo de Edição para Coleção em CancelEdit()
        /// </summary>
        [TestMethod()]
        public void ICollectionEditableTest_CancelEdit()
        {
            // Cria Objeto
            User user = new User();
            UserCollection userCollection = new UserCollection();

            // Muda Valores
            user.IDUser = 1;
            user.Login = "xpto";
            
            // Inicia Edição
            userCollection.BeginEdit();
            
            // Adiciona Usuário
            userCollection.Add(user);

            // Cancela Edição
            userCollection.CancelEdit();

            // Verifica o Mecanismo de Edição
            Assert.IsFalse(userCollection.Count > 0, "Falha ao Realizar o CancelEdit() na Coleção");
        }

        /// <summary>
        /// Valida o Mecanismo de Edição para Coleção em BeginEdit()
        /// </summary>
        [TestMethod()]
        public void ICollectionEditableTest_BeginEdit()
        {
            // Cria Objeto
            UserCollection userCollection = new UserCollection();

            // Inicia Edição
            userCollection.BeginEdit();
        }
    }
}